package com.itheima.filter;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import com.itheima.bean.CodeBean;
import com.itheima.utils.BaseContext;
import com.itheima.utils.JwtUtils;
import com.itheima.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 鉴权
 */
@Slf4j
@Order(-1)
@Component
public class AuthorizationFilter implements GlobalFilter {
    private static final AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //路径匹配
        String[] urls = {
                "/user/login",
                "/user/loginVerification",
                "/huanxin/user",
                "/system/users/login",
                "/system/users/verification"
        };
        //匹配放行
        for (String url : urls) {
            if (antPathMatcher.match(url, request.getURI().getPath())){
                return chain.filter(exchange);
            }
        }

        //获取当前用户的token
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("Authorization");
        if (token == null){
            log.error("用户未登录");
            exchange.getResponse().setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
            return exchange.getResponse().setComplete();
        }
        log.info("当前用户token:" + token);

        Claims claimsBody = JwtUtils.getClaimsBody(token);
        int i = JwtUtils.verifyToken(claimsBody);
        if (i == 1 || i == 2){
            log.error("登录信息已失效");
            exchange.getResponse().setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
            return exchange.getResponse().setComplete();
        }

        Long id = Convert.toLong(claimsBody.get("id"));
        log.info("当前用户登录id：" + id);

        //判断用户账号状态
//        if (ObjectUtil.isNotNull(redisTemplate.opsForValue().get(CodeBean.FREEZE_USER + id))){
//            log.error("你的账号已被冻结");
//            exchange.getResponse().setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
//            return exchange.getResponse().setComplete();
//        }

        redisTemplate.opsForValue().set(CodeBean.ID, Convert.toStr(id), 10L, TimeUnit.MINUTES);
        BaseContext.setThreadLocalId(id);
        ThreadLocalUtil.setId(id);
        log.info("过滤器解析当前登录用户id：{}", redisTemplate.opsForValue().get(CodeBean.ID));
        log.info("当前线程：{}", Thread.currentThread().getName());//reactor-http-nio-2

        return chain.filter(exchange);
    }
}
